package com.hhsj.design.pullableview.listview;

import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.animation.LinearInterpolator;
import android.widget.AbsListView;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.ListView;

import com.hhsj.design.pullableview.view.DefaultFooterLineView;
import com.hhsj.design.pullableview.view.DefaultLoadMoreView;
import com.hhsj.design.pullableview.view.DefaultRefreshView;
import com.hhsj.design.pullableview.FooterGoingToLoadMoreRunnable;
import com.hhsj.design.pullableview.HeaderGoingToRefreshRunnable;
import com.hhsj.design.pullableview.view.IFooterLineView;
import com.hhsj.design.pullableview.view.ILoadMoreView;
import com.hhsj.design.pullableview.ability.IPullAble;
import com.hhsj.design.pullableview.view.IRefreshView;


/**
 * HeaderLayout
 * HeaderParent
 * header 1
 * header 2
 * |
 * header n
 * RefreshParent
 * IRefreshView
 * list
 * item 1
 * item 2
 * |
 * item n
 * FooterLayout
 * FooterParent
 * footer 1
 * footer 2
 * |
 * footer n
 * FooterLineParent
 * IFooterLineView
 * LoadMoreParent
 * ILoadView
 */
public class RefreshListViewPro extends ListView implements AbsListView.OnScrollListener, IPullAble {

    private static String TAG = RefreshListViewPro.class.getSimpleName();

    /**
     * 1.如果listview滑出屏幕的距离为0时，下拉时header下面的view慢慢显示出来
     * 2.如果listview滑出屏幕的距离不为0时，执行其自身的滑动
     * 3.如果正在向下显示header下面的view时，上滑view也向上隐藏，隐藏完继续listview自身的滑动
     */

    private LinearLayout mHeaderLayout;
    private LinearLayout mFooterLayout;

    private LinearLayout mHeaderParent;//添加header的父布局
    private LinearLayout mFooterParent;//添加footer的父布局


    private FrameLayout mRefreshParent;//刷新布局的父布局
    private IRefreshView mIRefreshView;

    private FrameLayout mFooterLineParent;//底线布局的父布局
    private IFooterLineView mIFooterLineView;

    private FrameLayout mLoadMoreParent;//刷新布局的父布局
    private ILoadMoreView mILoadMoreView;

    private final int mTouchSlop;

    //功能开关
    private boolean supportElastic = false;//是否支持弹性
    private boolean supportRefresh = false;//是否支持刷新
    private boolean supportLoadMore = false;//是否支持加载更多刷新
    private boolean supportContinuePull = false;//支持继续下拉
    private boolean supportFooterLine = false;//是否支持底线

    //刷新视图的默认测量高度
    private int mRefreshViewHeight;

    //需要刷新的时候的刷新视图的高度
    private int mCanRefreshHeight;

    //需要继续刷新的时候刷新视图的高度
    private int mContinuePullHeight;

    //上拉加载等多的视图的高度
    private int mLoadMoreViewHeight;

    private int mCanLoadMoreHeight;//可执行上拉加载更多时的高度阈值

    //手势位置
    private float mLastX, mLastY;
    //正在拖拽
    private boolean mIsDrag = false;
    //正在显示底线
    private boolean isFooterLineShowing = false;

    //刷新控件的状态
    private HeaderState mHeaderState = HeaderState.NORMAL;
    //加载更多的状态
    private FooterState mFooterState = FooterState.NORMAL;

    private ViewGroup.LayoutParams headerParams;
    private HeaderGoingToRefreshRunnable mBackRefreshStateRunnable;

    private ViewGroup.LayoutParams footerParams;
    private FooterGoingToLoadMoreRunnable mFooterBackLoadMoreStateRunnable;

    private PullAbleListener mListener;
    //刷新视图的位置
    private int refreshViewMode = REFRESH_VIEW_MODE_TOP;

    //ListView 特有属性
    private int mTotalItemCount;//item的数量

    public RefreshListViewPro(Context context) {
        this(context, null);
    }

    public RefreshListViewPro(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RefreshListViewPro(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
        initHeader();
        initFooter();
        ViewTreeObserver observer = mHeaderLayout.getViewTreeObserver();
        if (null != observer) {
            observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    if (mIRefreshView != null) {
                        mRefreshViewHeight = mIRefreshView.getRefreshHeight();
                    }
                    ViewTreeObserver observer = getViewTreeObserver();
                    if (null != observer) {
                        observer.removeOnGlobalLayoutListener(this);
                    }
                }
            });
        }
        setOnScrollListener(this);
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {

    }


    /**
     * totalItemCount = itemCount + headerCount + footerCount
     *
     * @param view
     * @param firstVisibleItem
     * @param visibleItemCount
     * @param totalItemCount
     */
    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        if (mTotalItemCount != totalItemCount) {
            mTotalItemCount = totalItemCount;
        }
    }

    @Override
    public final void addHeaderView(View v) {
        mHeaderParent.addView(v);
    }

    @Override
    public final void addFooterView(View v) {
        mFooterParent.addView(v);
    }

    private void initHeader() {
        //添加头部布局
        mHeaderLayout = new LinearLayout(getContext());
        mHeaderLayout.setLayoutParams(new ListView.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        mHeaderLayout.setOrientation(LinearLayout.VERTICAL);
        super.addHeaderView(mHeaderLayout);

        //头部布局设立可添加的头部布局 用LinearLayout布局
        mHeaderParent = new LinearLayout(getContext());
        mHeaderParent.setLayoutParams(new LinearLayout.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        mHeaderParent.setOrientation(LinearLayout.VERTICAL);
        mHeaderLayout.addView(mHeaderParent);

        //设立可刷新布局 用FrameLayout布局
        mRefreshParent = new FrameLayout(getContext());
        mRefreshParent.setLayoutParams(new LinearLayout.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, 0));

        //根据可刷新布局的位置模式，设置布局的位置。
        if (refreshViewMode == REFRESH_VIEW_MODE_TOP) {
            mHeaderLayout.addView(mRefreshParent, 0);
        } else {
            mHeaderLayout.addView(mRefreshParent);
        }
    }

    private void initFooter() {
        //添加底部布局
        mFooterLayout = new LinearLayout(getContext());
        mFooterLayout.setOrientation(LinearLayout.VERTICAL);
        mFooterLayout.setGravity(Gravity.CENTER_HORIZONTAL);
        mFooterLayout.setLayoutParams(new ListView.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        super.addFooterView(mFooterLayout);

        //真的意义上的footer
        mFooterParent = new LinearLayout(getContext());
        mFooterParent.setLayoutParams(new LinearLayout.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        mFooterParent.setOrientation(LinearLayout.VERTICAL);
        mFooterLayout.addView(mFooterParent);

        //底线布局
        mFooterLineParent = new FrameLayout(getContext());
        mFooterLineParent.setLayoutParams(new LinearLayout.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        mFooterLayout.addView(mFooterLineParent);

        //刷新布局
        mLoadMoreParent = new FrameLayout(getContext());
        mLoadMoreParent.setLayoutParams(new LinearLayout.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, 0));
        mFooterLayout.addView(mLoadMoreParent);
    }


    private boolean isVerticalDrag(MotionEvent ev) {
        if (ev == null) {
            return false;
        }
        return Math.abs(mLastX - ev.getX()) < Math.abs(mLastY - ev.getY())//V方向运动大些
                && Math.abs(mLastY - ev.getY()) > mTouchSlop;//V方向运动大于最小阈值
    }


    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (mFooterState == FooterState.TO_LOAD
                || mFooterState == FooterState.LOADING
                || mFooterState == FooterState.TO_NORMAL) {
            return true;
        }

        if (!supportElastic
                && (!supportRefresh || mIRefreshView == null)
                && (!supportLoadMore || mILoadMoreView == null)) {
            return super.onInterceptTouchEvent(ev);
        }
        int action = ev.getActionMasked();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                mLastX = ev.getX();
                mLastY = ev.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                if (isVerticalDrag(ev)) {
                    return true;
                }
                break;
        }
        return super.onInterceptTouchEvent(ev);
    }


    /**
     * 1，当正在刷新时，消费所有事件
     * 2，当不支持刷新|头部刷新为空 && 当不支持加载更多|加载更多为空 的时候，
     * 表示刷新和加载更多功能不支持，此时应该由父类处理
     *
     * @param ev
     * @return
     */
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        Log.e(TAG, "HHSJ_STATE Header " + mHeaderState.toString() + "Footer " + mFooterState.toString());

        //自动出的状态下，不能触发事件
        if (mHeaderState == HeaderState.TO_REFRESH
                || mHeaderState == HeaderState.REFRESHING
                || mHeaderState == HeaderState.TO_NORMAL) {
            return false;
        }

        if (mFooterState == FooterState.TO_LOAD
                || mFooterState == FooterState.LOADING
                || mFooterState == FooterState.TO_NORMAL) {
            return false;
        }

        //需要处理header view里面的显示的话，要设置param，否则给父类自己来处理
        if (!supportElastic
                && (!supportRefresh || mIRefreshView == null)
                && (!supportLoadMore || mILoadMoreView == null)) {
            return super.onTouchEvent(ev);
        }

        //刷新布局的高度
        if (mIRefreshView != null) {
            if (mRefreshViewHeight <= 0) {
                mRefreshViewHeight = mIRefreshView.getRefreshHeight();
            }
            mCanRefreshHeight = mRefreshViewHeight;
            //继续下拉
            if (supportContinuePull) {
                mContinuePullHeight = mCanRefreshHeight + 180;
            }
        }

        if (mILoadMoreView != null) {
            if (mLoadMoreViewHeight <= 0) {
                mLoadMoreViewHeight = mILoadMoreView.getLoadMoreHeight();
            }
            mCanLoadMoreHeight = mLoadMoreViewHeight;
        }

        int action = ev.getActionMasked();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                Log.e(TAG, "HHSJ_ACTION ACTION_DOWN");
                mLastX = ev.getX();
                mLastY = ev.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                Log.e(TAG, "HHSJ_ACTION ACTION_MOVE");
                if (!mIsDrag && isVerticalDrag(ev)) {
                    mIsDrag = true;
                }
                if (mIsDrag) {
                    //下拉
                    if (mHeaderLayout.getTop() == 0
                            && ev.getY() > mLastY) {
                        if ((supportRefresh && mIRefreshView != null)) {
                            moveHeaderLayout(ev.getY() - mLastY);
                        } else if (supportElastic) {
                            moveHeaderLayout(ev.getY() - mLastY);
                        }
                    }
                    //当foot出现的时候，且 两次move的 foot 的 y 相同，表示，已经到底了
                    else if (getLastVisiblePosition() == mTotalItemCount - 1
                            && mLastY > ev.getY()) {
                        if ((supportLoadMore && mILoadMoreView != null)) {
                            moveFooterLayout(mLastY - ev.getY());
                        } else if (supportElastic) {
                            moveFooterLayout(mLastY - ev.getY());
                        }
                    }
                }
                break;
            case MotionEvent.ACTION_UP:
                mIsDrag = false;
                Log.e(TAG, "HHSJ_ACTION ACTION_UP");
                Log.e(TAG, "mHeaderLayout.getTop() = " + mHeaderLayout.getTop());
                Log.e(TAG, "First visiblePosition = " + getFirstVisiblePosition());
                if (mHeaderLayout.getTop() == 0 && getFirstVisiblePosition() == 0) {
                    Log.e(TAG, "params == " + headerParams);
                    if (headerParams == null) {
                        headerParams = mRefreshParent.getLayoutParams();
                    }
                    if ((supportRefresh && mIRefreshView != null)) {
                        if (headerParams.height <= 0) {
                            break;
                        }
                        //松开手指，后如果高度不够，回弹，高度够，执行刷新
                        boolean canRefresh = headerParams.height >= mCanRefreshHeight;
                        if (!canRefresh) {
                            headerBackNormal(headerParams.height);
                        } else {
                            boolean canContinuePull = supportContinuePull
                                    && headerParams.height >= mContinuePullHeight;
                            if (canContinuePull) {
                                if (null != mListener && mListener.onContinuePullAction()) {
                                    headerBackNormal(headerParams.height);
                                }
                            } else {
                                startRefreshHeight(headerParams.height, mCanRefreshHeight);
                            }
                        }
                    } else if (supportElastic) {
                        headerBackNormal(headerParams.height);
                    }

                } else if (getLastVisiblePosition() == getAdapter().getCount() - 1) {
                    //最后一个可见
                    if (footerParams == null) {
                        footerParams = mLoadMoreParent.getLayoutParams();
                    }
                    if ((supportLoadMore && mILoadMoreView != null)) {
                        if (footerParams.height <= 0) {
                            break;
                        }
                        //松开手指后，如果高度不够，回弹，高度够，执行刷新
                        boolean canLoadMore = footerParams.height >= mCanLoadMoreHeight;
                        if (canLoadMore) {
                            startLoadMoreHeight(footerParams.height, mCanLoadMoreHeight);
                        } else {
                            footerBackNormal(footerParams.height);
                        }
                    } else if (supportElastic) {
                        footerBackNormal(footerParams.height);
                    }
                }
                break;
            case MotionEvent.ACTION_CANCEL:
                Log.e(TAG, "HHSJ_ACTION ACTION_CANCEL");
                mIsDrag = false;
                break;

        }
        return super.onTouchEvent(ev);
    }

    private void headerBackNormal(int currentHeight) {
        if (currentHeight == 0) {
            return;
        }
        int duration = (int) Math.min(currentHeight / (float) mCanRefreshHeight * 500, 200);
        ValueAnimator animator = ValueAnimator.ofInt(currentHeight, 0);
        animator.setDuration(duration);
        animator.setInterpolator(new LinearInterpolator());
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int height = (int) animation.getAnimatedValue();
                Log.e(TAG, "updateHeight = " + height);
                if (height < 0) {
                    updateRefreshLayoutHeight(0);
                    animator.cancel();
                } else {
                    updateRefreshLayoutHeight(height);
                }
            }
        });

        animator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
                mHeaderState = HeaderState.TO_NORMAL;
                if (mIRefreshView != null) {
                    mIRefreshView.updateWithState(HeaderState.TO_NORMAL);
                }
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                mHeaderState = HeaderState.NORMAL;
                if (mIRefreshView != null) {
                    mIRefreshView.updateWithState(HeaderState.NORMAL);
                    mIRefreshView.stopAnim();
                }
            }

            @Override
            public void onAnimationCancel(Animator animation) {
                mHeaderState = HeaderState.NORMAL;
                if (mIRefreshView != null) {
                    mIRefreshView.updateWithState(HeaderState.NORMAL);
                    mIRefreshView.stopAnim();
                }
            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });

        animator.start();

//        if (mBackNormalStateRunnable == null) {
//            mBackNormalStateRunnable = new HeaderBackToNormalRunnable(mRefreshParent) {
//
//                @Override
//                public void onHeaderBackNormalStart() {
//                    mHeaderState = HeaderState.TO_NORMAL;
//                    if (mIRefreshView != null) {
//                        mIRefreshView.updateWithState(HeaderState.TO_NORMAL);
//                    }
//                }
//
//                @Override
//                protected void onHeaderBackNormalCompleted() {
//                    mHeaderState = HeaderState.NORMAL;
//                    if (mIRefreshView != null) {
//                        mIRefreshView.updateWithState(HeaderState.NORMAL);
//                        mIRefreshView.stopAnim();
//                    }
//                }
//
//                @Override
//                public void updateHeaderLayoutHeight(int movedHeight) {
//                    updateRefreshLayoutHeight(movedHeight);
//                }
//            };
//        }
//        mBackNormalStateRunnable.start(duration);
    }


    private void footerBackNormal(int currentHeight) {
        if (currentHeight == 0) {
            return;
        }

        int duration = (int) Math.min(currentHeight / (float) mCanLoadMoreHeight * 500, 200);

        ValueAnimator animator = ValueAnimator.ofInt(currentHeight, 0);
        animator.setDuration(duration);
        animator.setInterpolator(new LinearInterpolator());
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int height = (int) animation.getAnimatedValue();
                Log.e(TAG, "updateHeight = " + height);
                if (height < 0) {
                    updateLoadLayoutHeight(0);
                    animator.cancel();
                } else {
                    updateLoadLayoutHeight(height);
                }
            }
        });

        animator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
                mFooterState = FooterState.TO_NORMAL;
                if (mILoadMoreView != null) {
                    mILoadMoreView.updateWithState(FooterState.TO_NORMAL);
                }
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                mFooterState = FooterState.NORMAL;
                if (mILoadMoreView != null) {
                    mILoadMoreView.updateWithState(FooterState.NORMAL);
                    mILoadMoreView.stopAnim();
                }
            }

            @Override
            public void onAnimationCancel(Animator animation) {
                mFooterState = FooterState.NORMAL;
                if (mILoadMoreView != null) {
                    mILoadMoreView.updateWithState(FooterState.NORMAL);
                    mILoadMoreView.stopAnim();
                }
            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });

        animator.start();


//        if (mFooterBackNormalStateRunnable == null) {
//            mFooterBackNormalStateRunnable = new FooterBackToNormalRunnable(mLoadMoreParent) {
//
//                @Override
//                public void onFooterBackNormalStart() {
//                    mFooterState = FooterState.TO_NORMAL;
//                    if (mILoadMoreView != null) {
//                        mILoadMoreView.updateWithState(FooterState.TO_NORMAL);
//                    }
//                }
//
//                @Override
//                protected void onFooterBackNormalCompleted() {
//                    mFooterState = FooterState.NORMAL;
//                    if (mILoadMoreView != null) {
//                        mILoadMoreView.updateWithState(FooterState.NORMAL);
//                        mILoadMoreView.stopAnim();
//                    }
//                }
//
//                @Override
//                public void updateFooterLayoutHeight(int movedHeight) {
//                    updateLoadLayoutHeight(movedHeight);
//                    Log.e(TAG,"updateHeight = " + movedHeight);
//                }
//            };
//        }
//        mFooterBackNormalStateRunnable.start(duration);
    }

    /**
     * 立即恢复到NORMAL状态
     */
    private void footerBackNormalImmediately() {
        if (mILoadMoreView != null) {
            mILoadMoreView.updateWithState(FooterState.NORMAL);
            mILoadMoreView.stopAnim();
        }
        updateLoadLayoutHeight(0);
        mFooterState = FooterState.NORMAL;
    }

    /**
     * 当前高度回弹到开始刷新的高度
     *
     * @param currentHeight 当前高度
     * @param targetHeight  目标高度
     */
    private void startRefreshHeight(int currentHeight, int targetHeight) {
        int duration = (int) Math.min(currentHeight / (float) mCanRefreshHeight * 500, 200);
        if (mBackRefreshStateRunnable == null) {
            mBackRefreshStateRunnable = new HeaderGoingToRefreshRunnable(
                    mRefreshParent,
                    targetHeight) {

                @Override
                public void onToRefresh() {
                    mHeaderState = HeaderState.TO_REFRESH;
                    if (mIRefreshView != null) {
                        mIRefreshView.updateWithState(HeaderState.TO_REFRESH);
                    }
                }

                @Override
                public void doRefresh() {
                    mHeaderState = HeaderState.REFRESHING;
                    if (mIRefreshView != null) {
                        mIRefreshView.updateWithState(HeaderState.REFRESHING);
                        mIRefreshView.startAnim();
                    }
                    if (mListener != null) {
                        mListener.doRefresh();
                    }
                }

                @Override
                public void updateLayoutHeight(int movedHeight) {
                    updateRefreshLayoutHeight(movedHeight);
                }
            };
        }
        mBackRefreshStateRunnable.start(duration);
    }


    /**
     * 当前高度回弹到开始加载更多的高度
     *
     * @param currentHeight 当前高度
     * @param targetHeight  目标高度
     */
    private void startLoadMoreHeight(int currentHeight, int targetHeight) {
        int duration = (int) Math.min(currentHeight / (float) mCanLoadMoreHeight * 500, 200);
        if (mFooterBackLoadMoreStateRunnable == null) {
            mFooterBackLoadMoreStateRunnable = new FooterGoingToLoadMoreRunnable(
                    mLoadMoreParent,
                    targetHeight) {

                @Override
                public void onToLoad() {
                    mFooterState = FooterState.TO_LOAD;
                    if (mILoadMoreView != null) {
                        mILoadMoreView.updateWithState(FooterState.TO_LOAD);
                    }
                }

                @Override
                public void doLoadMore() {
                    mFooterState = FooterState.LOADING;
                    if (mILoadMoreView != null) {
                        mILoadMoreView.updateWithState(FooterState.LOADING);
                        mILoadMoreView.startAnim();
                    }
                    if (mListener != null) {
                        mListener.doLoadMore();
                    }
                }

                @Override
                public void updateLayoutHeight(int movedHeight) {
                    updateLoadLayoutHeight(movedHeight);
                }

            };
        }
        mFooterBackLoadMoreStateRunnable.start(duration);
    }


    /**
     * 根据move事件y的距离更新刷新布局的layoutparam的height
     *
     * @param eventDeltaY move事件的y方向距离
     */
    private void moveHeaderLayout(float eventDeltaY) {
        float changeHeight = (float) Math.pow(eventDeltaY, 0.85);
        headerParams = mRefreshParent.getLayoutParams();
        headerParams.height = (int) changeHeight;
        Log.e(TAG, "header move layout headerParams.height = " + headerParams.height);
        if (supportRefresh && mIRefreshView != null) {
            if (supportContinuePull) {
                if (headerParams.height > mContinuePullHeight) {
                    mIRefreshView.updateWithState(HeaderState.CAN_CONTINUE);
                } else if (headerParams.height > mCanRefreshHeight) {
                    mIRefreshView.updateWithState(HeaderState.CAN_REFRESH);
                } else {
                    mIRefreshView.updateWithState(HeaderState.FOR_REFRESH);
                }
            } else {
                if (headerParams.height > mCanRefreshHeight) {
                    mIRefreshView.updateWithState(HeaderState.CAN_REFRESH);
                } else {
                    mIRefreshView.updateWithState(HeaderState.FOR_REFRESH);
                }
            }
        }
        mHeaderLayout.requestLayout();

        //防止 ListView还没滚到底部，增加一层判断确保一定到底（如果可以向下滚动，先滚动1像素，如果不能就跳出了循环）
        while (canScrollVertically(-1)) {
            scrollListBy(-1);
        }
    }


    /**
     * 根据move事件y的距离更新刷新布局的LayoutParams的height
     *
     * @param eventDeltaY move事件的y方向距离
     */
    private void moveFooterLayout(float eventDeltaY) {
        float changeHeight = (float) Math.pow(eventDeltaY, 0.85);

        if (mILoadMoreView != null && mILoadMoreView.getLoadMoreView().getVisibility() == GONE) {
            mILoadMoreView.getLoadMoreView().setVisibility(VISIBLE);
        }

        footerParams = mLoadMoreParent.getLayoutParams();
        //保存上次
        int lastHeight = footerParams.height;

        footerParams.height = (int) (changeHeight + 0.5f);

        if (mILoadMoreView != null) {
            if (footerParams.height > mCanLoadMoreHeight) {
                mILoadMoreView.updateWithState(FooterState.CAN_LOAD);
            } else {
                mILoadMoreView.updateWithState(FooterState.FOR_LOAD);
            }
        }
        mLoadMoreParent.requestLayout();

        //让ListView滚到底部
        scrollListBy((int) (changeHeight + 0.5f) - lastHeight);

        //防止 ListView还没滚到底部，增加一层判断确保一定到底（如果可以向下滚动，先滚动1像素，如果不能就跳出了循环）
        while (canScrollVertically(1)) {
            scrollListBy(1);
        }
    }

    /**
     * 更新刷新视图高度
     *
     * @param height
     */
    private void updateRefreshLayoutHeight(int height) {
        headerParams = mRefreshParent.getLayoutParams();
        headerParams.height = height;
        mHeaderParent.requestLayout();
    }


    /**
     * 更新加载更多视图高度
     *
     * @param height
     */
    private void updateLoadLayoutHeight(int height) {
        if (height >= 0) {
            footerParams = mLoadMoreParent.getLayoutParams();
            footerParams.height = height;
            mFooterLayout.requestLayout();
        }
        while (canScrollVertically(1)) {
            scrollListBy(1);
        }
    }


    @Override
    public void setElasticEnable(boolean elasticEnable) {
        this.supportElastic = elasticEnable;
    }

    @Override
    public boolean isElasticEnable() {
        return supportElastic;
    }

    @Override
    public void setPullDownAbleListener(PullDownAbleListener listener) {

    }

    @Override
    public void setContinuePullEnable(boolean continuePullEnable) {
        this.supportContinuePull = continuePullEnable;
    }

    @Override
    public boolean isContinuePullEnable() {
        return supportContinuePull;
    }

    //是否支持刷新
    @Override
    public void setRefreshEnable(boolean refreshEnable) {
        if (supportRefresh != refreshEnable) {
            supportRefresh = refreshEnable;
            if (!supportRefresh) {
                mRefreshParent.removeAllViews();
                mRefreshParent.requestLayout();
                return;
            }
            if (mIRefreshView == null) {
                addRefreshView(null, 0);
            } else {
                if (mIRefreshView.getRefreshView().getParent() != mRefreshParent) {
                    if (null != mIRefreshView.getRefreshView().getParent()) {
                        ((ViewGroup) mIRefreshView.getRefreshView().getParent())
                                .removeView(mIRefreshView.getRefreshView());
                    }
                    mRefreshParent.addView(mIRefreshView.getRefreshView());
                }
                mHeaderLayout.requestLayout();
            }
        }
    }

    @Override
    public boolean isRefreshEnable() {
        return supportRefresh;
    }

    //添加刷新控件
    @Override
    public void addRefreshView(IRefreshView iRefreshView, int refreshHeight) {
        if (!supportRefresh) {
            return;
        }

        if (mRefreshParent.getChildCount() > 0) {
            mRefreshParent.removeAllViews();
        }
        mIRefreshView = (null == iRefreshView ? getDefaultRefreshView() : iRefreshView);
        FrameLayout.LayoutParams params = (FrameLayout.LayoutParams)
                mIRefreshView.getRefreshView().getLayoutParams();
        if (params == null) {
            throw new IllegalArgumentException("view must setLayoutParams with " +
                    "FrameLayout$LayoutParams");
        }

        if (params.height == ViewGroup.LayoutParams.MATCH_PARENT
                || params.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
            params.height = refreshHeight;
        }
        params.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
        mRefreshParent.addView(mIRefreshView.getRefreshView());
        mHeaderLayout.requestLayout();

    }


    //设置弹性位置
    @Override
    public void setRefreshViewMode(int mode) {
        if (mode != refreshViewMode) {
            if (mode == REFRESH_VIEW_MODE_MID || mode == REFRESH_VIEW_MODE_TOP) {
                refreshViewMode = mode;
                if (mHeaderLayout == null || mHeaderLayout.getChildCount() != 2) {
                    return;
                }
                if (refreshViewMode == REFRESH_VIEW_MODE_TOP) {
                    if (mHeaderLayout.getChildAt(0) == mHeaderParent) {
                        mHeaderLayout.removeView(mHeaderParent);
                        mHeaderLayout.addView(mHeaderParent);
                    }
                } else {
                    if (mHeaderLayout.getChildAt(1) == mHeaderParent) {
                        mHeaderLayout.removeView(mHeaderParent);
                        mHeaderLayout.addView(mHeaderParent, 0);
                    }
                }
            } else {
                Log.e(TAG, "无效的刷新控件位置");
            }
        }
    }


    @Override
    public int getRefreshViewMode() {
        return refreshViewMode;
    }


    public void addLoadMoreView() {
        if (mILoadMoreView == null) {
            return;
        }
        if (!supportLoadMore) {
            setLoadMoreEnable(true);
        }
        if (mLoadMoreParent.getChildCount() > 0) {
            mLoadMoreParent.removeAllViews();
        }
        FrameLayout.LayoutParams params = (FrameLayout.LayoutParams)
                mILoadMoreView.getLoadMoreView().getLayoutParams();
        params.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
        mLoadMoreParent.addView(mILoadMoreView.getLoadMoreView());
        mFooterLayout.requestLayout();
    }

    /**
     * 添加底部
     *
     * @param iLoadMoreView
     * @param defaultFooterHeight
     */
    @Override
    public void setLoadMoreView(ILoadMoreView iLoadMoreView, int defaultFooterHeight) {
        mILoadMoreView = (null == iLoadMoreView ? getDefaultFooterView() : iLoadMoreView);
        FrameLayout.LayoutParams params = (FrameLayout.LayoutParams)
                mILoadMoreView.getLoadMoreView().getLayoutParams();
        if (params == null) {
            throw new IllegalArgumentException("View must setLayoutParams with " +
                    "FrameLayout$LayoutParams");
        }
        if (params.height == ViewGroup.LayoutParams.MATCH_PARENT
                || params.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
            params.height = defaultFooterHeight;
        }
    }

    public void setLoadMoreViewBgColor(int colorInt) {
        mLoadMoreParent.setBackgroundColor(colorInt);
    }

    /**
     * 上拉加载更多功能开关
     * 关闭上拉加载
     * 如果底线功能关了
     *
     * @param loadMoreEnable
     */
    @Override
    public void setLoadMoreEnable(boolean loadMoreEnable) {
        if (supportLoadMore == loadMoreEnable) {
            return;
        }
        supportLoadMore = loadMoreEnable;

        //如果需要展示加载更多，则先要隐藏底线
        if (supportLoadMore) {
            setFooterLineEnable(false);
            addLoadMoreView();
            if (null != mILoadMoreView
                    && mILoadMoreView.getLoadMoreView() != null
                    && mILoadMoreView.getLoadMoreView().getParent() != mLoadMoreParent) {
                if (mILoadMoreView.getLoadMoreView().getParent() != null) {
                    ((ViewGroup) mILoadMoreView.getLoadMoreView().getParent())
                            .removeView(mILoadMoreView.getLoadMoreView());
                }
                mLoadMoreParent.addView(mILoadMoreView.getLoadMoreView());
            }
        } else {
            if (mFooterState == FooterState.LOADING) {
                footerBackNormalImmediately();
            }
            mLoadMoreParent.removeAllViews();
        }
        mLoadMoreParent.requestLayout();
    }

    @Override
    public boolean isLoadMoreEnable() {
        return supportLoadMore;
    }


    //底线在刷新之上
    @Override
    public void addFooterLineView(IFooterLineView iFooterLineView) {
        if (!supportFooterLine) {
            return;
        }
        mIFooterLineView = (null == iFooterLineView ? getDefaultFooterLineView() : iFooterLineView);
        mFooterLineParent.removeAllViews();
        mFooterLineParent.addView(mIFooterLineView.getFootLineView());
    }

    /**
     * 启用/关闭底线功能
     * 前提：
     * 1。LoadMore情况下, 设置ture无效
     * 2。相同设置，设置无效
     * <p>
     * 如果关闭底线功能，将设置底线为展示为false
     *
     * @param footerLineEnable
     */
    @Override
    public void setFooterLineEnable(boolean footerLineEnable) {
        if (footerLineEnable && supportLoadMore) {
            return;
        }
        if (supportFooterLine == footerLineEnable) {
            return;
        }
        supportFooterLine = footerLineEnable;
        if (!supportFooterLine) {
            showFooterLine(false);
        }
    }

    @Override
    public boolean isFooterLineEnable() {
        return supportFooterLine;
    }

    /**
     * @param show
     */
    @Override
    public void showFooterLine(boolean show) {
        if (!supportFooterLine) {
            isFooterLineShowing = false;
            if (null != mIFooterLineView) {
                mIFooterLineView.getFootLineView().setVisibility(GONE);
            }
        } else {
            if (isFooterLineShowing == show) {
                return;
            }
            //在可以loadmore的情况下，不可以展示底线
            if (supportLoadMore) {
                return;
            }
            isFooterLineShowing = show;
            if (isFooterLineShowing) {
                if (mIFooterLineView == null) {
                    addFooterLineView(null);
                }
                mIFooterLineView.getFootLineView().setVisibility(VISIBLE);
            } else {
                if (null != mIFooterLineView) {
                    mIFooterLineView.getFootLineView().setVisibility(GONE);
                }
            }
        }
    }

    @Override
    public boolean isFooterLineShowing() {
        return isFooterLineShowing;
    }


    @Override
    public void setFooterLineEnableAndShow() {
        setFooterLineEnable(true);
        showFooterLine(true);
    }

    /**
     * 前置条件
     * 1，supportLoadMore 置为false
     * 2，supportFootLine 置为true
     * 3，展示footerLine
     */
    @Override
    public void setLoadMoreDisableAndShowFooterLine() {
        if (supportLoadMore) {
            setLoadMoreEnable(false);
        }

        if (!supportFooterLine) {
            setFooterLineEnable(true);
        }

        showFooterLine(true);
    }

    @Override
    public IFooterLineView getFooterLineView() {
        return mIFooterLineView;
    }

    @Override
    public void setPullAbleListener(PullAbleListener listener) {
        mListener = listener;
    }

    @Override
    public void stopRefresh() {
        if (mIRefreshView != null) {
            mIRefreshView.updateWithState(HeaderState.NORMAL);
            mIRefreshView.stopAnim();
        }
        headerBackNormal(headerParams.height);
    }

    /**
     * 停止加载更多
     */
    @Override
    public void stopLoadMore() {
        footerBackNormalImmediately();
    }

    private ILoadMoreView getDefaultFooterView() {
        return new DefaultLoadMoreView(getContext());
    }

    private IRefreshView getDefaultRefreshView() {
        return new DefaultRefreshView(getContext());
    }

    private IFooterLineView getDefaultFooterLineView() {
        return new DefaultFooterLineView(getContext());
    }

}